import React, { useCallback, useEffect, useRef, useState } from "react";
import { Map, Marker, NavigationControl, Polyline, MapvglLayer, MapvglView } from "react-bmapgl";
import provinces from './data/province.json'
import coords from './data/province2coord.json'
import prov2index from './data/province2index.json'
import index2prov from './data/index2province.json'
import { Label } from './component/Label'
import { UIButton } from './component/UIButton'
import { Evolution, MAX_STEP } from './algo'
// @MapApiLoaderHOC({ ak: 'IdOPw2frEdodw4iaY7KUWMOqD4grhRKc' })
import './styles/toastui_chart.min.css'
import { BarChart, LineChart } from '@toast-ui/react-chart'

interface AppState {
  msg: '开始' | '暂停' | '重来' | '刷新',
  bestSeq: number[],
  distance: number,
  cnt: number
}


let points: BMapGL.Point[]



export const App: React.FC = (props) => {

  const [state, setState] = useState<AppState>({
    bestSeq: [...Object.values(prov2index)],
    msg: '开始',
    distance: 0,
    cnt: 0
  })

  const { current: algoRef } = useRef<Evolution>(new Evolution(state.bestSeq))
  const chartRef = useRef<LineChart>()
  let itera = algoRef.iter()
  let { current: id } = useRef<NodeJS.Timeout>()

  const algoTimer = useCallback(() => {
    id = setInterval(() => {
      let item = itera.next().value as {
        bestSeq: number[];
        cnt: number;
        best: number;
        worst: number;
        avg: number;
      }

      let { bestSeq, cnt, best, avg, worst } = item

      if (cnt === MAX_STEP) {
        setState(state => ({
          ...state,
          msg: '刷新'
        }))
        algoRef.reset()
        clearInterval(id)
        
        return
      }

      // console.log(initOptionsRef.current)
      chartRef.current.getInstance().addData([best, worst, avg], cnt.toString())
      // console.log(dataRef.current.series[0].data)

      if (bestSeq instanceof Array) {
        setState(state => ({
          ...state,
          bestSeq,
          distance: best,
          cnt
        }))
      }
    }, 300)
  }, [])

  //处理按钮逻辑
  const cbButton = useCallback((msg: AppState['msg']) => {
    if (msg == '开始') {
      setState(state => ({
        ...state,
        msg: '暂停'
      }))
      algoTimer()

    }
    else if (msg == '暂停') {
      setState(state => ({
        ...state,
        msg: '开始'
      }))
      clearInterval(id)
    }
    else if (msg == '刷新') {
      window.location.href=window.location.href
    }
    else {
      setState({
        ...state,
        msg: '暂停'
      })
      algoRef.reset()
      itera = algoRef.iter()
      algoTimer()
      dataRef.current = {...initDataRef.current}
      chartRef.current.getInstance().setData(dataRef.current)
    }
  }, [])

  points = state.bestSeq.map(index => {
    const { lng, lat } = coords[index2prov[String(index)]]
    return new BMapGL.Point(lng, lat)
  })


  // componentDidMount() {

  // }


  const dataRef = useRef({
    categories: [
      '0'
    ],
    series: [
      {
        name: '最优解',
        data: [0],
      },
      {
        name: '最差解',
        data: [0],
      },
      {
        name: '平均值',
        data: [0],
      },
    ],
  })

  const initDataRef = useRef<any>({
    categories: [
      '0'
    ],
    series: [
      {
        name: '最优解',
        data: [0],
      },
      {
        name: '最差解',
        data: [0],
      },
      {
        name: '平均值',
        data: [0],
      },
    ],
  })

  const optionsRef = useRef({
    chart: { width: 700, height: 200 },
    xAxis: {
      title: '迭代(次)',
    },
    yAxis: {
      title: '距离（KM）',
    },
    theme: {
      chart: {
        backgroundColor: 'rgba(255, 255, 255, 0.4)'
      }
    }
  })

  return (
    <>
      <div style={{
        top: '40px',
        left: '20px',
        width: '200px',
        height: '130px',
        border: '2px solid tomato',
        borderRadius: '5px',
        zIndex: 9999,
        position: 'absolute',
        backgroundColor: 'wheat',
      }}>
        <Label
          distance={state.distance}
          cnt={state.cnt}
        />
        <UIButton
          msg={state.msg}
          cbButton={cbButton}
        />
      </div>
      <LineChart
        ref={chartRef}
        data={dataRef.current}
        options={optionsRef.current}
        style={{
          position: 'absolute',
          zIndex: 9999,
          left: '250px',
          background: 'rgba(255, 255, 255, 0.5)'
        }}
      />
      <Map
        center={new BMapGL.Point(104.402544, 37.928216)}
        zoom={5}
        enableDragging={false}
        style={{
          height: '100vh',
          width: '100vw',
          zIndex: 99999
        }}>
        {/* {
        this.points.map((point, index) => 
          (<Marker
            key={index}
            position={point}
            icon={'location'}
            
            map={undefined}
          />))
      } */}
        <Polyline
          path={points}
          strokeColor="#ff6600"
          strokeWeight={1}
          map={undefined}
        />

        {/* <NavigationControl map={undefined} /> */}
        <MapvglView effects={['bright']} map={undefined}>
          <MapvglLayer
            type="PointLayer"
            data={points.map(({ lng, lat }) => ({
              geometry: {
                type: 'Point',
                coordinates: [lng, lat],
              }
            }))}
            options={{
              blend: 'lighter',
              size: 12,
              color: 'rgb(255, 53, 0, 0.6)'
            }}
            map={undefined}
            view={undefined}
          />
        </MapvglView>
      </Map>
    </>
  );
}